package cn.daomeng.firebird.core.exception;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import cn.daomeng.firebird.core.log.LogFactory;
import cn.daomeng.firebird.core.mvc.ApiResponse;

/**
 *  统一异常处理(AOP)
 * @author wf.shu
 * @since 2019-03-05 14:23
 */
@RestControllerAdvice
@SuppressWarnings("rawtypes")
public class FirebirdExceptionAdvice {

	@Autowired
	public I18nMessageService i18nMessageService;

	/** JSR303 参数不合法校验*/
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ExceptionHandler(value = ConstraintViolationException.class)
	public ApiResponse constraintViolationException(ConstraintViolationException ex){
		Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
		List<String> errorMsgList = new ArrayList<String>();
		String errorInfo = "";
		if(constraintViolations != null && constraintViolations.size() > 0){
			for (ConstraintViolation str : constraintViolations) {
				String message = str.getMessage();
				errorMsgList.add(message);
				errorInfo = errorInfo + message + ",";
			}
			errorInfo = errorInfo.substring(0,errorInfo.length() - 1);
		}

		FirebirdException e = new FirebirdException(BizCode.getBizCodeFromEnum(BizCodeEnumDefault.BAD_REQUEST), errorInfo,ex);
        LogFactory.error("参数校验失败", e);
		return FirebirdExceptionResponseHandler.vaildhander(e);
	}

	/** JSR303 参数为空校验*/
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ExceptionHandler(value = MissingServletRequestParameterException.class)
	public ApiResponse missingServletRequestParameterException( MissingServletRequestParameterException ex){
		String parameterName = ex.getParameterName();
		FirebirdException e = new FirebirdException(BizCode.getBizCodeFromEnum(BizCodeEnumDefault.BAD_REQUEST), "MissingServletRequestParameterException 缺少参数：" + parameterName,ex);
        LogFactory.error("缺少参数", e);
		return FirebirdExceptionResponseHandler.vaildhander(e);

	}

	/**
	* 400 - Bad Request
	*/
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ExceptionHandler(HttpMessageNotReadableException.class)
	public ApiResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        FirebirdException ce = new FirebirdException(BizCode.getBizCodeFromEnum(BizCodeEnumDefault.BAD_REQUEST),"HttpMessageNotReadableException",e);
        LogFactory.error("参数解析失败", ce);
		return FirebirdExceptionResponseHandler.hander(ce);
	}

	/**
	* 405 - Method Not Allowed
	*/
	@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	public ApiResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        FirebirdException ce = new FirebirdException(BizCode.getBizCodeFromEnum(BizCodeEnumDefault.METHOD_NOT_ALLOWED),"HttpRequestMethodNotSupportedException",e);
        LogFactory.error("不支持当前请求方法", ce);
		return FirebirdExceptionResponseHandler.hander(ce);
	}

	/**
	* 415 - Unsupported Media Type
	*/
	@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
	@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
	public ApiResponse handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
        FirebirdException ce = new FirebirdException(BizCode.getBizCodeFromEnum(BizCodeEnumDefault.UNSUPPORTED_MEDIA_TYPE),"HttpMediaTypeNotSupportedException",e);
        LogFactory.error("不支持当前媒体类型", ce);
		return FirebirdExceptionResponseHandler.hander(ce);
	}

	/**
	 * 500 - Internal Server Error
	 * <br/>
	 * 通用异常返回
	 * @author  WeiFei.Shu
	 * @since   2018年12月28日 下午5:42:32
	 * @param
	 * @return exceptionResponse
	 */
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(FirebirdException.class)
	ApiResponse handleCalorieException(FirebirdException e) {
		LogFactory.error(e.getBizCode().getName() , e);
		int code = e.getBizCode().getCode();
		String[] value = e.getBizCode().getValue();
		Locale locale = LocaleContextHolder.getLocale();
		String message = i18nMessageService.getMessage(locale,code+"", value);
		return ApiResponse.response(code,null,message);
	}

	/**
	 * 500 - Internal Server Error
	 * <br/>
	 * 通用异常返回
	 * @author  WeiFei.Shu
	 * @since   2018年12月28日 下午5:42:32
	 * @param
	 * @return exceptionResponse
	 */
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(Exception.class)
	ApiResponse handleException(Exception e) {
		LogFactory.error(e.getMessage() , e);
		return FirebirdExceptionResponseHandler.hander(e);
	}
	
}
